home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / util / primitives / safeeval.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  11KB  |  275 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import sys
  5. import inspect
  6. import compiler.ast as compiler
  7. import thread
  8. import time
  9. DEBUG = False
  10. all_ast_nodes = frozenset((lambda .0: for name, obj in .0:
  11. if inspect.isclass(obj) and issubclass(obj, compiler.ast.Node):
  12. namecontinue)(inspect.getmembers(compiler.ast)))
  13. import __builtin__
  14. all_builtins = set(dir(__builtin__))
  15.  
  16. def classname(obj):
  17.     return obj.__class__.__name__
  18.  
  19.  
  20. def is_valid_ast_node(name):
  21.     return name in all_ast_nodes
  22.  
  23.  
  24. def is_valid_builtin(name):
  25.     return name in all_builtins
  26.  
  27.  
  28. def get_node_lineno(node):
  29.     if not node.lineno or node.lineno:
  30.         pass
  31.     return 0
  32.  
  33. unallowed_ast_nodes = frozenset(('AssAttr', 'AssList', 'AssName', 'AssTuple', 'Assert', 'Assign', 'AugAssign', 'Backquote', 'Break', 'CallFunc', 'Class', 'Continue', 'Decorators', 'Exec', 'For', 'From', 'Function', 'Getattr', 'If', 'Import', 'Print', 'Printnl', 'Raise', 'Return', 'TryExcept', 'TryFinally', 'While', 'Yield'))
  34. unallowed_builtins = frozenset(('__import__', 'classmethod', 'compile', 'delattr', 'dir', 'eval', 'execfile', 'file', 'getattr', 'globals', 'hasattr', 'input', 'intern', 'locals', 'open', 'raw_input', 'reload', 'setattr', 'vars'))
  35. for ast_name in unallowed_ast_nodes:
  36.     pass
  37.  
  38. for name in unallowed_builtins:
  39.     pass
  40.  
  41.  
  42. def is_unallowed_ast_node(kind):
  43.     return kind in unallowed_ast_nodes
  44.  
  45.  
  46. def is_unallowed_builtin(name):
  47.     return name in unallowed_builtins
  48.  
  49. unallowed_attr = frozenset(('im_class', 'im_func', 'im_self', 'func_code', 'func_defaults', 'func_globals', 'func_name', 'tb_frame', 'tb_next', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_locals'))
  50.  
  51. def is_unallowed_attr(name):
  52.     if not name.startswith('__') or name.endswith('__'):
  53.         pass
  54.     return name in unallowed_attr
  55.  
  56.  
  57. class SafeEvalError(object):
  58.     
  59.     def __init__(self, errmsg, lineno):
  60.         self.errmsg = errmsg
  61.         self.lineno = lineno
  62.  
  63.     
  64.     def __str__(self):
  65.         return 'line %d : %s' % (self.lineno, self.errmsg)
  66.  
  67.  
  68.  
  69. class SafeEvalASTNodeError(SafeEvalError):
  70.     pass
  71.  
  72.  
  73. class SafeEvalBuiltinError(SafeEvalError):
  74.     pass
  75.  
  76.  
  77. class SafeEvalAttrError(SafeEvalError):
  78.     pass
  79.  
  80.  
  81. class SafeEvalVisitor(object):
  82.     
  83.     def __init__(self):
  84.         self.errors = []
  85.         for ast_name in all_ast_nodes:
  86.             if getattr(self, 'visit' + ast_name, None):
  87.                 continue
  88.             
  89.             if is_unallowed_ast_node(ast_name):
  90.                 setattr(self, 'visit' + ast_name, self.fail)
  91.                 continue
  92.             setattr(self, 'visit' + ast_name, self.ok)
  93.         
  94.  
  95.     
  96.     def walk(self, ast):
  97.         self.visit(ast)
  98.         return self.errors == []
  99.  
  100.     
  101.     def visit(self, node, *args):
  102.         fn = getattr(self, 'visit' + classname(node))
  103.         if DEBUG:
  104.             self.trace(node)
  105.         
  106.         fn(node, *args)
  107.         for child in node.getChildNodes():
  108.             self.visit(child, *args)
  109.         
  110.  
  111.     
  112.     def visitName(self, node, *args):
  113.         name = node.getChildren()[0]
  114.         lineno = get_node_lineno(node)
  115.         if is_unallowed_builtin(name):
  116.             self.errors.append(SafeEvalBuiltinError("access to builtin '%s' is denied" % name, lineno))
  117.         elif is_unallowed_attr(name):
  118.             self.errors.append(SafeEvalAttrError("access to attribute '%s' is denied" % name, lineno))
  119.         
  120.  
  121.     
  122.     def visitGetattr(self, node, *args):
  123.         name = node.attrname
  124.         lineno = get_node_lineno(node)
  125.         if is_unallowed_attr(name):
  126.             self.errors.append(SafeEvalAttrError("access to attribute '%s' is denied" % name, lineno))
  127.         
  128.  
  129.     
  130.     def ok(self, node, *args):
  131.         pass
  132.  
  133.     
  134.     def fail(self, node, *args):
  135.         lineno = get_node_lineno(node)
  136.         self.errors.append(SafeEvalASTNodeError("execution of '%s' statements is denied" % classname(node), lineno))
  137.  
  138.     
  139.     def trace(self, node):
  140.         print classname(node)
  141.         for attr in dir(node):
  142.             if attr[:2] != '__':
  143.                 print '    ', '%-15.15s' % attr, getattr(node, attr)
  144.                 continue
  145.         
  146.  
  147.  
  148.  
  149. class SafeEvalException(Exception):
  150.     pass
  151.  
  152.  
  153. class SafeEvalCodeException(SafeEvalException):
  154.     
  155.     def __init__(self, code, errors):
  156.         self.code = code
  157.         self.errors = errors
  158.  
  159.     
  160.     def __str__(self):
  161.         return '\n'.join((lambda .0: for err in .0:
  162. str(err))(self.errors))
  163.  
  164.  
  165.  
  166. class SafeEvalContextException(SafeEvalException):
  167.     
  168.     def __init__(self, keys, errors):
  169.         self.keys = keys
  170.         self.errors = errors
  171.  
  172.     
  173.     def __str__(self):
  174.         return '\n'.join((lambda .0: for err in .0:
  175. str(err))(self.errors))
  176.  
  177.  
  178.  
  179. class SafeEvalTimeoutException(SafeEvalException):
  180.     
  181.     def __init__(self, timeout):
  182.         self.timeout = timeout
  183.  
  184.     
  185.     def __str__(self):
  186.         return 'Timeout limit execeeded (%s secs) during exec' % self.timeout
  187.  
  188.  
  189.  
  190. def exec_timed(code, context, timeout_secs):
  191.     signal_finished = False
  192.     
  193.     def alarm(secs):
  194.         
  195.         def wait(secs):
  196.             for n in xrange(timeout_secs):
  197.                 time.sleep(1)
  198.                 if signal_finished:
  199.                     break
  200.                     continue
  201.             
  202.  
  203.         thread.start_new_thread(wait, (secs,))
  204.  
  205.     
  206.     try:
  207.         alarm(timeout_secs)
  208.         exec code in context
  209.         signal_finished = True
  210.     except KeyboardInterrupt:
  211.         (None, None)
  212.         (None, None)
  213.         raise SafeEvalTimeoutException(timeout_secs)
  214.     except:
  215.         (None, None)
  216.  
  217.  
  218.  
  219. def safe_eval(code, context = None, timeout_secs = 5):
  220.     if context is None:
  221.         context = { }
  222.     
  223.     ctx_errkeys = []
  224.     ctx_errors = []
  225.     for key, obj in context.items():
  226.         if inspect.isbuiltin(obj):
  227.             ctx_errkeys.append(key)
  228.             ctx_errors.append("key '%s' : unallowed builtin %s" % (key, obj))
  229.         
  230.         if inspect.ismodule(obj):
  231.             ctx_errkeys.append(key)
  232.             ctx_errors.append("key '%s' : unallowed module %s" % (key, obj))
  233.             continue
  234.     
  235.     if ctx_errors:
  236.         raise SafeEvalContextException(ctx_errkeys, ctx_errors)
  237.     
  238.     ast = compiler.parse(code)
  239.     checker = SafeEvalVisitor()
  240.     if checker.walk(ast):
  241.         exec_timed(code, context, timeout_secs)
  242.     else:
  243.         raise SafeEvalCodeException(code, checker.errors)
  244.  
  245.  
  246. def pprintAst(ast, indent = '  ', stream = sys.stdout):
  247.     rec_node(ast, 0, indent, stream.write)
  248.  
  249.  
  250. def rec_node(node, level, indent, write):
  251.     pfx = indent * level
  252.     if isinstance(node, compiler.ast.Node):
  253.         write(pfx)
  254.         write(node.__class__.__name__)
  255.         write('(')
  256.         if any((lambda .0: for child in .0:
  257. isinstance(child, compiler.ast.Node))(node.getChildren())):
  258.             for i, child in enumerate(node.getChildren()):
  259.                 if i != 0:
  260.                     write(',')
  261.                 
  262.                 write('\n')
  263.                 rec_node(child, level + 1, indent, write)
  264.             
  265.             write('\n')
  266.             write(pfx)
  267.         else:
  268.             write(', '.join((lambda .0: for child in .0:
  269. repr(child))(node.getChildren())))
  270.         write(')')
  271.     else:
  272.         write(pfx)
  273.         write(repr(node))
  274.  
  275.